package config

import (
	"data-system/tools"
	"flag"
	"log"
	"os"
	"runtime"

	"github.com/spf13/pflag"
	"github.com/spf13/viper"
)

type Config struct {
	Project            string `json:"project"`
	FileSuffix         string `json:"fileSuffix"`
	FileConflictSuffix string `json:"fileConflictSuffix"`
	AssetDir           string `json:"assetDir"`
	ConfigDir          string `json:"configDir"`

	ConflictDir string `json:"conflictDir"`
	DatabaseDir string `json:"databaseDir"`

	EnumDir       string `json:"enumDir"`
	SerialMetaDir string `json:"serialMetaDir"`

	MongoDataDir     string `json:"mongoDataDir"`
	MongoLogDir      string `json:"mongoLogDir"`
	MongoSoftwareDir string `json:"mongoSoftwareDir"`
	MongoUri         string `json:"mongoUri"`
	MongoDataBase    string `json:"mongoDataBase"`
}

var cfg *Config

func Cfg() *Config {
	if cfg == nil {
		cfg = &Config{
			Project:            viper.GetString("project"),
			FileSuffix:         viper.GetString("fileSuffix"),
			FileConflictSuffix: viper.GetString("fileConflictSuffix"),
			AssetDir:           viper.GetString("assetDir"),
			ConfigDir:          viper.GetString("configDir"),
			ConflictDir:        viper.GetString("conflictDir"),
			EnumDir:            viper.GetString("enumDir"),
			SerialMetaDir:      viper.GetString("serialMetaDir"),
			DatabaseDir:        viper.GetString("databaseDir"),

			MongoSoftwareDir: viper.GetString("mongoSoftwareDir"),
			MongoUri:         viper.GetString("mongoUri"),
			MongoDataDir:     viper.GetString("mongoDataDir"),
			MongoLogDir:      viper.GetString("mongoLogDir"),
			MongoDataBase:    viper.GetString("mongoDataBase"),
		}
	}
	return cfg
}

func Load() {
	// 1. 初始化 Viper
	viper.SetConfigName("config")   // 配置文件名 (不含扩展名)
	viper.SetConfigType("yaml")     // 如果你的配置文件没有扩展名，这行是必须的
	viper.AddConfigPath("./config") // 查找配置文件的路径
	viper.AddConfigPath(".")

	currentDir, _ := os.Getwd()
	var prefixDir string
	osType := runtime.GOOS
	if osType == "windows" {
		prefixDir = "e:/editor"
	} else if osType == "darwin" {
		prefixDir = "/Users/editor"
	}
	var defaultConfig = map[string]string{
		"fileSuffix":         ".xlsx",
		"fileConflictSuffix": ".xlsx",
		"assetDir":           prefixDir + "/assets",
		"configDir":          prefixDir + "/config",

		"enumDir":       prefixDir + "/enums",
		"serialMetaDir": currentDir + "/meta/serial",

		"conflictDir":  prefixDir + "/conflict",
		"databaseDir":  prefixDir + "/database",
		"mongoDataDir": prefixDir + "/mongo/data",
		"mongoLogDir":  prefixDir + "/mongo/log",
	}

	flag.String("project", "", "项目code")
	flag.String("fileSuffix", defaultConfig["fileSuffix"], "数据文件后缀")
	flag.String("fileConflictSuffix", defaultConfig["fileConflictSuffix"], "冲突文件后缀")
	flag.String("assetDir", defaultConfig["assetDir"], "资源目录")
	flag.String("configDir", defaultConfig["configDir"], "数据文件目录")

	flag.String("enumDir", defaultConfig["enumDir"], "枚举目录")
	flag.String("serialMetaDir", defaultConfig["serialMetaDir"], "序列化元数据目录")

	flag.String("conflictDir", defaultConfig["conflictDir"], "冲突文件目录")
	flag.String("databaseDir", defaultConfig["databaseDir"], "badger数据目录")

	flag.String("mongoDataDir", defaultConfig["mongoDataDir"], "mongo服务器数据目录")
	flag.String("mongoLogDir", defaultConfig["mongoLogDir"], "mongo服务器日志目录")
	flag.String("MongoSoftwareDir", "", "mongo服务器软件目录")
	flag.String("MongoUri", "127.0.0.1:27017", "mongo服务器ip:port")
	flag.String("MongoDataBase", "g-editor", "mongo服务器数据库名称")

	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
	pflag.Parse()
	viper.BindPFlags(pflag.CommandLine)
	tools.CreateDirIfNotExist(viper.GetString("assetDir"))
	tools.CreateDirIfNotExist(viper.GetString("configDir"))
	tools.CreateDirIfNotExist(viper.GetString("conflictDir"))
	tools.CreateDirIfNotExist(viper.GetString("databaseDir"))
	tools.CreateDirIfNotExist(viper.GetString("enumDir"))
	tools.CreateDirIfNotExist(viper.GetString("serialMetaDir"))
	tools.CreateDirIfNotExist(viper.GetString("mongoDataDir"))
	tools.CreateDirIfNotExist(viper.GetString("mongoLogDir"))
	log.Printf("【%v】启动项目......", viper.GetString("project"))
}

func GetConfig() map[string]interface{} {
	cfg1 := tools.ObjToMap(Cfg())
	return cfg1
}

func SetConfig(assetDir, configDir, pubDir, project *string) {
	if assetDir != nil {
		viper.Set("assetDir", assetDir)
		tools.CreateDirIfNotExist(viper.GetString("mongoLogDir"))
	}
	if configDir != nil {
		viper.Set("configDir", configDir)
		tools.CreateDirIfNotExist(viper.GetString("mongoLogDir"))
	}
	if project != nil {
		viper.Set("project", project)
	}
	if pubDir != nil {
		conflictDir := *pubDir + "/conflict"
		databaseDir := *pubDir + "/database"
		mongoDataDir := *pubDir + "/mongo/data"
		mongoLogDir := *pubDir + "/mongo/log"
		viper.Set("conflictDir", conflictDir)
		viper.Set("databaseDir", databaseDir)
		viper.Set("mongoDataDir", mongoDataDir)
		viper.Set("mongoLogDir", mongoLogDir)
		tools.CreateDirIfNotExist(conflictDir)
		tools.CreateDirIfNotExist(databaseDir)
		tools.CreateDirIfNotExist(mongoDataDir)
		tools.CreateDirIfNotExist(mongoLogDir)
	}
	viper.WatchConfig()
	cfg = nil
}
